<script>
export default {
  name: 'BdTableColumn',
  props: {
    label: {
      type: [String, Number],
    },
    prop: {
      type: [String, Number],
    },
    minWidth: {
      type: [String, Number],
      default: 80,
    },
    width: {
      type: [String, Number],
      default: 80,
    },
    fixed: {
      type: String,
      default: 'none',
    },
    mergeAllRows: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      isTableColumn: true,
      childrenColumns: [],
      columnInfo: {},
    };
  },
  created() {
    this.columnInfo = {
      label: this.label,
      prop: this.prop,
      fixed: this.fixed,
      mergeAllRows: this.mergeAllRows,
      width: this.minWidth > this.width ? this.minWidth : this.width,
      childrenColumns: this.childrenColumns,
      renderCell: this.renderCell,
      renderHeader: this.renderHeader,
    };
    Object.keys(this.$props).forEach((key) => {
      this.$watch(key, () => {
        this.columnInfo.label = this.label;
        this.columnInfo.prop = this.prop;
        this.columnInfo.fixed = this.fixed;
        this.columnInfo.mergeAllRows = this.mergeAllRows;
        this.columnInfo.width = this.minWidth > this.width ? this.minWidth : this.width;
        this.columnInfo.childrenColumns = this.childrenColumns;
        this.columnInfo.renderCell = this.renderCell;
        this.columnInfo.renderHeader = this.renderHeader;
      });
    });
  },
  mounted() {
    const parent = this.getParent();
    const parentChildrenColumns = parent.childrenColumns;
    const { columnInfo, childrenColumns } = this;
    columnInfo.childrenColumns = childrenColumns;
    const index = parentChildrenColumns.indexOf(columnInfo);
    const indexInNode = this.getSlotIndex();
    if (index < 0) {
      parentChildrenColumns.splice(indexInNode, 0, columnInfo);
    }
  },
  beforeDestroy() {
    const parent = this.getParent();
    const parentChildrenColumns = parent.childrenColumns;
    const { columnInfo } = this;
    const index = parentChildrenColumns.indexOf(columnInfo);
    if (index > -1) {
      parentChildrenColumns.splice(index, 1);
    }
  },
  methods: {
    renderHeader() {
      return this.$scopedSlots.header ? this.$scopedSlots.header({
        column: {
          label: this.label,
          prop: this.prop,
        },
      }) : this.label;
    },
    renderCell(data) {
      const val = this.objectKey(data, `${this.prop}`, '-');
      let render = this.$slots.default || (val === '' ? '-' : val);
      render = this.$scopedSlots.default ? this.$scopedSlots.default({
        row: data,
        column: {
          label: this.label,
          prop: this.prop,
        },
      }) : render;
      return render;
    },
    getParent() {
      let parent = this.$parent;
      while (!parent.isTable && !parent.isTableColumn && parent.$parent) {
        parent = parent.$parent;
      }
      return parent;
    },
    getSlotIndex() {
      const parent = this.getParent();
      const slotList = [...parent.$refs.hiddenColumn.children];
      return slotList.indexOf(this.$el);
    },
    objectKey(obj, keyPath, str = null) {
      if (keyPath === null || keyPath === undefined || keyPath === '') {
        return str;
      }
      const keys = `${keyPath}`.split('.');
      let length = keys.length;
      let curr = obj;
      while (length) {
        const key = keys.shift();
        if (key && curr && curr[key] !== undefined) {
          curr = curr[key];
          // eslint-disable-next-line no-plusplus
          length--;
        } else {
          return str;
        }
      }
      return curr;
    },
  },
  render() {
    return (
      <div className="hidden-column" ref="hiddenColumn">{this.$slots.default}</div>
    );
  },
};
</script>
<style lang="less" scoped>
.hidden-column{
  display: none;
}
</style>
